import json

from django.contrib.contenttypes.models import ContentType
from django.db import transaction
from rest_framework.viewsets import generics

from utils.customer_modelviewset import CustomModelViewSet
from utils.exception import CustomError
from utils.permissions import IsMemberUser
from utils import response_error, response_ok
from apps.member.models import MemberRecord
from apps.system.models import Upload
from .filters import CommentFilter
from .models import Comment
from .serializers import CommentSerializers


class CommentChildListViewSet(generics.ListAPIView):
    queryset = Comment.objects.filter(delete=False)
    serializer_class = CommentSerializers

    def filter_queryset(self, queryset):
        f = CommentFilter(self.request.GET, queryset=queryset)
        return f.qs


class CommentListViewSet(generics.ListAPIView):
    queryset = Comment.objects.filter(delete=False, parent=None)
    serializer_class = CommentSerializers

    def filter_queryset(self, queryset):
        f = CommentFilter(self.request.GET, queryset=queryset)
        return f.qs


class CommentViewSet(CustomModelViewSet):
    # permission_classes = (IsMemberUser,)
    queryset = Comment.objects.filter(delete=False)
    serializer_class = CommentSerializers

    def create(self, request, *args, **kwargs):
        try:
            content = request.POST.get('content', None)
            model_name = request.POST.get('model_name', None)
            object_id = request.POST.get('object_id', None)
            img_ids = request.POST.get('img_ids', None)
            parse_content = request.POST.get('parseContent', None)
            # parseContent = json.loads(request.data['parseContent'])
            if img_ids:
                img_ids = [int(v) for v in img_ids.split(',')]
            if not content or not model_name or not object_id or not parse_content:
                return response_error('缺少参数')

            # 回复
            parent_id = request.POST.get('parent_id', None)
            parent = None
            if parent_id:
                parent = Comment.objects.filter(id=parent_id).first()

            content_type = ContentType.objects.get(model=model_name.lower())
            if not content_type:
                return response_error('未找到(%s)对应实体' % content_type)
            # ContentType表对象有model_class() 方法，取到对应model
            EntityModel = content_type.model_class()
            instance = EntityModel.objects.filter(id=object_id).first()
            if not instance:
                return response_error('未找到实体(%s)对应的（id=%s）实例' % (EntityModel.__name__, object_id))

            with transaction.atomic():
                comment = Comment.objects.create(content_object=instance, user=self.request.user, content=content,
                                                 parse_content=parse_content, parent=parent)
                if img_ids:
                    comment.images.add(*Upload.objects.filter(pk__in=img_ids))

                MemberRecord.objects.create(content_object=comment, user=self.request.user,
                                            operate=MemberRecord.COMMENT, describe='发表了评论')

        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            import traceback
            traceback.print_exc()
            return response_error(str(e))
        return response_ok()

    def destroy(self, request, *args, **kwargs):
        try:
            with transaction.atomic():
                instance = self.get_object()
                if instance.member == self.request.user:
                    instance.delete = True
                    instance.save()
        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            return response_error(str(e))
        return response_ok()
